import static com.googlecode.javacv.cpp.opencv_core.NORM_L2;
import static com.googlecode.javacv.cpp.opencv_highgui.CV_LOAD_IMAGE_GRAYSCALE;
import static opencvtest.OpenCVUtils.loadAndShowOrExit;

import java.io.File;

import com.googlecode.javacv.cpp.opencv_core.CvMat;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_features2d.BFMatcher;
import com.googlecode.javacv.cpp.opencv_features2d.DMatch;
import com.googlecode.javacv.cpp.opencv_features2d.DescriptorExtractor;
import com.googlecode.javacv.cpp.opencv_features2d.KeyPoint;
import com.googlecode.javacv.cpp.opencv_nonfree.SIFT;

/**    
 * 文件名：JavaCvSiftMatch.java    
 *    
 * 版本信息：    
 * 日期：2014年3月12日    
 * xyj 足下 xyj 2014     
 * 版权所有    
 *    
 */

/**
 * @项目名称：opencv-test
 * @类名称：JavaCvSiftMatch
 * @类描述：
 * @创建人：zhuyi
 * @创建时间：2014年3月12日 下午4:13:05
 * @修改人：zhuyi
 * @修改时间：2014年3月12日 下午4:13:05
 * @修改备注：
 * @version
 * 
 */
public class JavaCvSiftMatch {

    public static void main(String[] args) {

        IplImage[] images = new IplImage[] {
                loadAndShowOrExit(new File("E:/image-test/z1.jpg"), CV_LOAD_IMAGE_GRAYSCALE),
                loadAndShowOrExit(new File("E:/image-test/z2.jpg"), CV_LOAD_IMAGE_GRAYSCALE) };

        int nFeatures = 0;
        int nOctaveLayers = 3;
        float contrastThreshold = 0.03f;
        int edgeThreshold = 10;
        float sigma = 1.6f;
        SIFT sift = new SIFT(nFeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma);
        DescriptorExtractor siftDesc = DescriptorExtractor.create("SIFT");

        KeyPoint[] keyPoints = new KeyPoint[2];
        CvMat[] descriptors = new CvMat[2];

        // Detect SURF features and compute descriptors for both images
        for (int i = 0; i < images.length; i++) {
            keyPoints[i] = new KeyPoint();
            sift.detect(images[i], null, keyPoints[i]);
            // Create CvMat initialized with empty pointer, using simply `new
            // CvMat()` leads to an exception.
            descriptors[i] = new CvMat(null);
            siftDesc.compute(images[i], keyPoints[i], descriptors[i]);
        }

        // Create feature matcher
        BFMatcher matcher = new BFMatcher(NORM_L2, true);

        DMatch matches = new DMatch();
        // "match" is a keyword in Scala, to avoid conflict between a keyword
        // and a method match of the BFMatcher,
        // we need to enclose method name in ticks: `match`.
        matcher.match(descriptors[0], descriptors[1], matches, null);
        System.out.println("Matched: " + matches.capacity());
        System.out.println("Matched distance " + matches.distance());

        // Select only 25 best matches
        // DMatch bestMatches = selectBest(matches, 25);

        // Draw best matches
        // IplImage imageMatches = IplImage.create(new CvSize(images[0].width()
        // + images[1].width(), images[0].height()),
        // images[0].depth(), 3);
        // drawMatches(images[0], keyPoints[0], images[1], keyPoints[1],
        // bestMatches, imageMatches, CvScalar.BLUE,
        // CvScalar.RED, null, DrawMatchesFlags.DEFAULT);
        // show(imageMatches, "Best SURF Feature Matches");

    }

    // private DMatch selectBest(DMatch matches, int numberToSelect) {
    // // Convert to Scala collection, and sort
    // val sorted = toArray(matches).sortWith(_ compare _)
    //
    // // Select the best, and return in native vector
    // toNativeVector(sorted.take(numberToSelect))
    // }
}
